package com.prs.crm.action.oa;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Result;
import org.courser.struts.BaseAction;
import org.courser.ui.PaginationSupport;
import org.hibernate.annotations.Cascade;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Property;
import org.hibernate.criterion.Restrictions;

import com.prs.crm.annotation.Clew;
import com.prs.crm.context.AppContext;
import com.prs.crm.context.Constrains;
import com.prs.crm.context.ToolKits;
import com.prs.crm.domain.doc.DocLevel;
import com.prs.crm.domain.doc.Document;
import com.prs.crm.domain.hr.Person;
import com.prs.crm.domain.oa.Notice;
import com.prs.crm.domain.oa.ReferSchedule;
import com.prs.crm.domain.oa.Schedule;
import com.prs.crm.service.doc.DocLevelService;
import com.prs.crm.service.oa.NoticeService;
import com.prs.crm.service.oa.ReferScheduleService;
import com.prs.crm.service.oa.ScheduleService;

public class ScheduleAction extends BaseAction {

	private static final long serialVersionUID = 1L;

	private static final String key = "com.prs.crm.oa.taskDockey";

	private Schedule schedule;
	private ScheduleService scheduleService;
	private PaginationSupport pagination;
	private Integer[] scheduleIds;
	private Collection<DocLevel> docLevels;

	private ReferSchedule referSchedule;
	private ReferScheduleService referScheduleService;
	private Integer[] referScheduleIds;
	private NoticeService noticeService;
	private DocLevelService docLevelService;

	private String current;
	private File upload;
	private String uploadFileName;
	private Person currentPerson;

	private Collection<Document> relatDocs;
	private boolean existStor;

	@Action("listExeSchedule")
	public String listExeSchedule() {
		DetachedCriteria criteria = this.getPaginationHelper().createQuery(
				Schedule.class);
		pagination = this.getPaginationHelper().prepare(pagination);
		Person person = AppContext.getAccountContext().currentUser();
		criteria.add(Property.forName("exePerson").eq(person));
		criteria.add(Restrictions.or(Restrictions.eq("state",
				Constrains.TASK_EXECUTE), Restrictions.eq("state",
				Constrains.TASK_NOTPASS)));
		this.setPagination(this.getScheduleService().listByPage(criteria,
				pagination));
		return SUCCESS;
	}

	@Action("listAllotSchedule")
	public String listAllotSchedule() {
		DetachedCriteria criteria = this.getPaginationHelper().createQuery(
				Schedule.class);
		pagination = this.getPaginationHelper().prepare(pagination);
		Person person = AppContext.getAccountContext().currentUser();
		criteria.add(Property.forName("allotPerson").eq(person));
		this.setPagination(this.getScheduleService().listByPage(criteria,
				pagination));
		return SUCCESS;
	}

	@Action("listReferSchedule")
	public String listReferSchedule() {
		DetachedCriteria criteria = this.getPaginationHelper().createQuery(
				ReferSchedule.class);
		pagination = this.getPaginationHelper().prepare(pagination);
		Person person = AppContext.getAccountContext().currentUser();
		criteria.createAlias("schedule", "s");
		criteria.add(Restrictions.eq("s.exePerson", person));
		this.setPagination(this.getReferScheduleService().listByPage(criteria,
				pagination));
		return SUCCESS;
	}

	@Action("listAuditingSchedule")
	public String listAuditingSchedule() {
		DetachedCriteria criteria = this.getPaginationHelper().createQuery(
				ReferSchedule.class);
		pagination = this.getPaginationHelper().prepare(pagination);
		Person person = AppContext.getAccountContext().currentUser();
		criteria.createAlias("schedule", "s");
		criteria.add(Restrictions.eq("s.allotPerson", person));
		criteria.add(Restrictions.eq("s.state", Constrains.TASK_AUDITING));
		criteria.add(Restrictions.eq("state", Constrains.TASK_AUDITING));
		this.setPagination(this.getReferScheduleService().listByPage(criteria,
				pagination));
		return SUCCESS;
	}

	@Action("editReferSchedule")
	public String editRefer() {
		return SUCCESS;
	}

	@Clew(results = { "success" })
	@Cascade( { org.hibernate.annotations.CascadeType.ALL,
			org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
	@Action(value = "saveReferSchedule", results = { @Result(name = "success", type = "redirect", location = "listReferSchedule") })
	public String saveRefer() {
		this.setPrompt("提交日程成功!");
		schedule.setState(Constrains.TASK_AUDITING);
		referSchedule.setSchedule(schedule);
		referSchedule.setState(Constrains.TASK_AUDITING);
		this.getReferScheduleService().saveReferSchedule(referSchedule, upload,
				uploadFileName);

		String msg = schedule.getExePerson().getResume().getName() + "已提交工作日程:"
				+ schedule.getTitle() + "，请审核";
		Notice notice = new Notice();
		notice.setTitle("工作日程审核");
		notice.setContent(msg);

		this.getNoticeService().sendNotice(notice, schedule.getRecorder());
		return SUCCESS;
	}

	@Clew(results = { "success" })
	@Action(value = "auditingPass", results = {
			@Result(name = "success", type = "redirect", location = "listAuditingSchedule"),
			@Result(name = "error", type = "chain", location = "listAuditingSchedule") })
	public String auditingPass() {
		if (referScheduleIds == null) {
			this.addActionError("请选择要审核的日程");
			return ERROR;
		} else {
			this.getReferScheduleService().auditingPass(referScheduleIds);
			return SUCCESS;
		}
	}

	@Action(value = "auditingNotPass", results = {
			@Result(name = "success", type = "redirect", location = "listAuditingSchedule"),
			@Result(name = "error", type = "chain", location = "listAuditingSchedule") })
	public String auditingNotPass() {
		if (referScheduleIds == null) {
			this.addActionError("请选择要打回的日程");
			return ERROR;
		} else {
			this.getReferScheduleService().auditingNotPass(referScheduleIds);
			return SUCCESS;
		}
	}

	@Action(value = "removeReferSchedule", results = { @Result(name = "success", type = "redirect", location = "listReferSchedule") })
	public String removeRefer() {
		this.getReferScheduleService().batchRemove(referScheduleIds);
		return SUCCESS;
	}

	@Action("listSchedule")
	public String execute() {
		DetachedCriteria criteria = this.getPaginationHelper().createQuery(
				Schedule.class);
		pagination = this.getPaginationHelper().prepare(pagination);
		this.setPagination(this.getScheduleService().listByPage(criteria,
				pagination));
		return SUCCESS;
	}

	@Action("viewReferSchedule")
	public String viewRefer() {
		return SUCCESS;
	}

	@Action("viewSchedule")
	public String view() {
		return SUCCESS;
	}

	@Action("editSchedule")
	public String edit() throws Exception {
		this.setCurrentPerson(AppContext.getAccountContext().currentUser());
		this.setCurrent(ToolKits.currentDate());

		this.prepare();
		if (!existStor) {
			this.getStorage().remove(key);
			if (schedule != null) {
				relatDocs = new ArrayList<Document>();
				this.getStorage().save(key, relatDocs);
				if (schedule.getDocs() != null) {
					relatDocs.addAll(schedule.getDocs());
				}
			}
		}
		if (this.getStorDocs() == null) {
			relatDocs = new ArrayList<Document>();
			this.getStorage().save(key, relatDocs);
		}

		return SUCCESS;
	}

	@Clew(results = { "success" })
	@Action(value = "saveSchedule", results = {
			@Result(name = "success", type = "redirect", location = "listSchedule"),
			@Result(name = "error", type = "chain", location = "editSchedule") })
	public String save() {
		if (schedule.getTitle() == null
				|| "".equals(schedule.getTitle().trim())) {
			addActionError("主题不能为空");
			return ERROR;
		}
		if (schedule.getCreattime() == null) {
			addActionError("创建时间不能为空");
			return ERROR;
		}
		if (schedule.getExePerson() == null) {
			addActionError("执行人不能为空");
			return ERROR;
		}
		if (schedule.getAllotPerson() == null) {
			addActionError("下达人不能为空");
			return ERROR;
		}
		if (schedule.getBeginTime() == null) {
			addActionError("开始时间不能为空");
			return ERROR;
		}
		if (schedule.getEndTime() == null) {
			addActionError("结束不能为空");
			return ERROR;
		}
		if(schedule.getBeginTime().getTime()>schedule.getEndTime().getTime()){
			addActionError("结束时间不能在开始时间以前");
			return ERROR;
		}
		if (schedule.getAwoke() == null
				|| "".equals(schedule.getAwoke().trim())) {
			addActionError("提醒不能为空");
			return ERROR;
		}
		if (schedule.getLevel() == null
				|| "".equals(schedule.getLevel().trim())) {
			addActionError("级别不能为空");
			return ERROR;
		}
		this.setPrompt("工作日程下达成功!");
		schedule.setState(Constrains.TASK_EXECUTE);
		this.getScheduleService()
				.saveSchedule(schedule, upload, uploadFileName);

		String msg = "工作日程:" + schedule.getTitle() + "已下达，请审核";
		Notice notice = new Notice();
		notice.setTitle("执行工作日程");
		notice.setContent(msg);

		this.getNoticeService().sendNotice(notice, schedule.getExePerson());
		return SUCCESS;
	}

	@Action(value = "removeSchedule", results = {
			@Result(name = "success", type = "redirect", location = "listSchedule"),
			@Result(name = "error", type = "chain", location = "listSchedule") })
	public String remove() {
		if (scheduleIds == null) {
			this.addActionError("请选择要删除的日程");
			return ERROR;
		}
		this.getScheduleService().batchRemove(scheduleIds);
		return SUCCESS;
	}

	private void prepare() {
		docLevels = this.getDocLevelService().getAllDocLevel();
	}

	public Schedule getSchedule() {
		return schedule;
	}

	public void setSchedule(Schedule schedule) {
		this.schedule = schedule;
	}

	public ScheduleService getScheduleService() {
		return scheduleService;
	}

	public void setScheduleService(ScheduleService scheduleService) {
		this.scheduleService = scheduleService;
	}

	public PaginationSupport getPagination() {
		return pagination;
	}

	public void setPagination(PaginationSupport pagination) {
		this.pagination = pagination;
	}

	public Integer[] getScheduleIds() {
		return scheduleIds;
	}

	public void setScheduleIds(Integer[] scheduleIds) {
		this.scheduleIds = scheduleIds;
	}

	public String getCurrent() {
		return current;
	}

	public void setCurrent(String current) {
		this.current = current;
	}

	public File getUpload() {
		return upload;
	}

	public void setUpload(File upload) {
		this.upload = upload;
	}

	public String getUploadFileName() {
		return uploadFileName;
	}

	public void setUploadFileName(String uploadFileName) {
		this.uploadFileName = uploadFileName;
	}

	public void setCurrentPerson(Person currentPerson) {
		this.currentPerson = currentPerson;
	}

	public Person getCurrentPerson() {
		return currentPerson;
	}

	public ReferSchedule getReferSchedule() {
		return referSchedule;
	}

	public void setReferSchedule(ReferSchedule referSchedule) {
		this.referSchedule = referSchedule;
	}

	public ReferScheduleService getReferScheduleService() {
		return referScheduleService;
	}

	public void setReferScheduleService(
			ReferScheduleService referScheduleService) {
		this.referScheduleService = referScheduleService;
	}

	public void setReferScheduleIds(Integer[] referScheduleIds) {
		this.referScheduleIds = referScheduleIds;
	}

	public Integer[] getReferScheduleIds() {
		return referScheduleIds;
	}

	public void setNoticeService(NoticeService noticeService) {
		this.noticeService = noticeService;
	}

	public NoticeService getNoticeService() {
		return noticeService;
	}

	public Collection<Document> getRelatDocs() {
		return relatDocs;
	}

	public void setRelatDocs(Collection<Document> relatDocs) {
		this.relatDocs = relatDocs;
	}

	public static String getKey() {
		return key;
	}

	public Collection<DocLevel> getDocLevels() {
		return docLevels;
	}

	public void setDocLevels(Collection<DocLevel> docLevels) {
		this.docLevels = docLevels;
	}

	public DocLevelService getDocLevelService() {
		return docLevelService;
	}

	public void setDocLevelService(DocLevelService docLevelService) {
		this.docLevelService = docLevelService;
	}

	@SuppressWarnings("unchecked")
	public Collection<Document> getStorDocs() {
		return (Collection<Document>) this.getStorage().get(key);
	}

}
